package tech.xs.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.entity.BaseEntity;
import tech.xs.common.framework.domain.enums.DataSourceTypeEnum;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.domain.model.PageResult;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.sys.domain.bo.dict.ManualEditChildDictDataBo;
import tech.xs.sys.domain.bo.dict.PageChildDictDataBo;
import tech.xs.sys.domain.entity.SysChildDict;
import tech.xs.sys.domain.entity.SysChildDictData;
import tech.xs.sys.domain.entity.SysDict;
import tech.xs.sys.domain.entity.SysDictData;
import tech.xs.sys.service.SysChildDictDataService;
import tech.xs.sys.service.SysChildDictService;
import tech.xs.sys.service.SysDictDataService;
import tech.xs.sys.service.SysDictService;

import javax.annotation.Resource;

/**
 * 子字典数据管理
 *
 * @author 沈家文
 * @since 2023/5/24$ 17:12$
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/dict/child/data")
public class SysChildDictDataController {

    @Resource
    private SysDictService sysDictService;
    @Resource
    private SysChildDictService sysChildDictService;
    @Resource
    private SysChildDictDataService sysChildDictDataService;
    @Resource
    private SysDictDataService sysDictDataService;

    /**
     * 分页查询子字典数据
     *
     * @param bo 请求参数
     * @return 查询结果
     * @author 沈家文
     * @since 2023/5/24 17:23
     */
    @GetMapping("/list/page")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public PageResult<SysChildDictData> page(@ModelAttribute PageChildDictDataBo bo) {
        return PageResult.success(sysChildDictDataService.selectJoinListPage(bo.page(), SysChildDictData.class, bo.query()));
    }

    /**
     * 添加或修改子字典数据
     *
     * @param bo 请求参数
     * @return 响应数据
     * @author 沈家文
     * @since 2023/5/30 19:48
     */
    @PostMapping("/saveOrUpdate/manual")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public ApiResult<SysChildDictData> manualEdit(@Validated @RequestBody ManualEditChildDictDataBo bo) {
        SysDict dict = sysDictService.getOne(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getCode, bo.getDictCode()));
        if (dict == null) {
            return ApiResult.error("字典不存在 dictCode:" + bo.getDictCode());
        }

        SysChildDict childDict = sysChildDictService.getOne(Wrappers.<SysChildDict>lambdaQuery()
                .eq(SysChildDict::getDictId, dict.getId())
                .eq(SysChildDict::getCode, bo.getChildDictCode())
        );
        if (childDict == null) {
            return ApiResult.error("子字典不存在 dictCode:" + bo.getDictCode() + " childDictCode:" + bo.getChildDictCode());
        }

        SysDictData dictData = sysDictDataService.getOne(Wrappers.<SysDictData>lambdaQuery()
                .eq(SysDictData::getDictId, dict.getId())
                .eq(SysDictData::getCode, bo.getDictDataCode())
        );
        if (dictData == null) {
            return ApiResult.error("字典数据不存在 dictCode:" + bo.getDictCode() + " dictDataCode:" + bo.getDictDataCode());
        }

        long existCount = sysChildDictDataService.count(Wrappers.<SysChildDictData>lambdaQuery()
                .eq(SysChildDictData::getChildDictId, childDict.getId())
                .eq(SysChildDictData::getDictDataId, dictData.getId())
                .ne(bo.getId() != null, BaseEntity::getId, bo.getId()));
        if (existCount > 0) {
            return ApiResult.error("子字典数据已经存在");
        }

        SysChildDictData saveData = new SysChildDictData();
        BeanUtil.copyProperties(bo, saveData);
        saveData.setDictId(dict.getId());
        saveData.setChildDictId(childDict.getId());
        saveData.setDictDataId(dictData.getId());
        saveData.setSource(DataSourceTypeEnum.Manual);

        if (bo.getId() != null) {
            SysChildDictData dbData = sysChildDictDataService.getOne(Wrappers.<SysChildDictData>lambdaQuery().eq(BaseEntity::getId, bo.getId()));
            if (dbData == null) {
                return ApiResult.error("根据id在系统中未查询到数据");
            }
            if (!dbData.getDictId().equals(saveData.getDictId())) {
                return ApiResult.error("绑定的字典不允许修改");
            }
            if (!dbData.getChildDictId().equals(saveData.getChildDictId())) {
                return ApiResult.error("绑定的子字典不允许修改");
            }
            if (DataSourceTypeEnum.SystemGeneration.equals(dbData.getSource())) {
                return ApiResult.error("系统生成字典数据禁止修改");
            }
        }

        log.info("手动更新或保存子字典数据:" + saveData);
        sysChildDictDataService.saveOrUpdate(saveData);
        sysDictService.reloadChildDictCache(dict.getCode(), childDict.getCode());
        return ApiResult.success(saveData);
    }

    @DeleteMapping("/delete/id")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public ApiResult<Long> deleteByCode(@RequestParam Long id) {
        if (id == null) {
            return ApiResult.error("id不能为空");
        }
        SysChildDictData childDictData = sysChildDictDataService.getById(id);
        if (childDictData == null) {
            return ApiResult.error("字典数据不存在或已删除");
        }

        SysChildDict childDict = sysChildDictService.getById(childDictData.getChildDictId());
        if (childDict == null) {
            return ApiResult.error("数据绑定的子字典不存在");
        }

        SysDict dict = sysDictService.getById(childDictData.getDictId());
        if (dict == null) {
            return ApiResult.error("数据绑定的字典不存在");
        }
        log.info("删除子字典数据:" + childDictData);
        sysChildDictDataService.removeById(id);
        sysDictService.reloadChildDictCache(dict.getCode(), childDict.getCode());
        return ApiResult.success(id);
    }


}
